#ifndef USE_MIPS_ASSEMBLY
#define USE_MIPS_ASSEMBLY
#include <mips/regdef.h>
#include <sys/syscall.h>

# reg: s0=k, s1=i, s2=e
# stack: 24 SRA, 0 LTA, 0 ABA

#define ARRAYSIZE 28
#define WORDS 24
#define FP 16
#define GP 12
#define S2 8
#define S1 4
#define S0 0
#define STACK_SIZE 24

	.text
	.align 2
	.globl shellsort
	.ent shellsort
shellsort:
	.frame $fp, STACK_SIZE, ra
	.set noreorder
	.cpload t9
	.set reorder

	# armo el stack
	subu	sp, sp, STACK_SIZE
	sw	$fp, FP(sp)
	.cprestore GP
	sw	s2, S2(sp)
	sw	s1, S1(sp)
	sw	s0, S0(sp)
	sw	a0, WORDS(sp)
	sw	a1, ARRAYSIZE(sp)
	move	$fp, sp
	
	#principal
	move	s0, a1
for1:
	srl	s0, s0, 1
	beq	s0, zero, term1
	#
	li	s1, 0
for2:
	sltu	t0, s1, s0
	beq	t0, zero, term2
	#
	move	s2, s1
while3:
	addu	t1, s0, s2
	sltu	t0, t1, a1
	beq	t0, zero, term3
	sll	t6, s2, 2
	addu	t6, t6, a0
	sll	t7, t1, 2
	addu	t7, t7, a0

	lw	t0, (t6)
	lw	t1, (t7)
	# strcasecmp
	j	casecmp
casecmp_cont
	addu	t0, t0, 1
	addu	t1, t1, 1
casecmp:
	lbu	t2, (t0)
	lbu	t3, (t1)
	beq	t2, zero, casecmp_term
	beq	t3, zero, casecmp_term
	beq	t2, t3, casecmp_cont
casecmp_case2:
	sgeu	t4, t2, 'a'
	sleu	t5, t2, 'z'
	and	t4, t4, t5
	beq	t4, zero, casecmp_case3
	subu	t2, t2, 'a'-'A'
	beq	t2, t3, casecmp_cont
casecmp_case3:
	sgeu	t4, t3, 'a'
	sleu	t5, t3, 'z'
	and	t4, t4, t5
	beq	t4, zero, casecmp_term
	subu	t3, t3, 'a'-'A'
	beq	t2, t3, casecmp_cont
casecmp_term:
	subu	v0, t2, t3
	blez	v0, suma4

	# swap
	lw	t0, (t6)
	lw	t1, (t7)
	sw	t0, (t7)
	sw	t1, (t6)
	#
	sltu	t0, s0, s2
	beq	t0, zero, suma4
	
	subu	s2, s2, s0
	j	term4
suma4:
	addu	s2, s2, s0
term4:
	#
	j	while3
term3:
	#
	addi	s1, s1, 1
	j	for2
term2:
	#
	j	for1
term1:
	# restauro registros y destruyo stack
	move	sp, $fp
	lw	$fp, FP(sp)
	lw	s2, S2(sp)
	lw	s1, S1(sp)
	lw	s0, S0(sp)
	lw	v0, WORDS(sp)
	addu	sp, sp, STACK_SIZE
	jr	ra
	.end shellsort

#endif
